package test.myorm.handler;

import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;

import jodd.bean.BeanUtilBean;
import test.myorm.core.ResultMap;
import test.myorm.core.Sql;

public class ResultSetHandler {
	
	public static final List<Class> baseClasses = Arrays.asList(int.class,float.class,char.class,long.class,double.class);
	public static final List<Class> extraBaseClasses = Arrays.asList(
			Integer.class,Float.class,Character.class,Long.class,Double.class,String.class);
	
	public List list(Object obj) {
		if(obj instanceof List) {
			return (List)obj;
		} else {
			List list = new ArrayList();
			list.add(obj);
			return list;
		}
	}
	
	public List handle(Sql sql, ResultSet rs) {
		try {
			ResultSetMetaData rsmd = rs.getMetaData();
			int count = rsmd.getColumnCount();
			ResultMap resultMap = sql.getResultMap();
			Class<?> returnClass = resultMap.getClazz();
			if(baseClasses.contains(returnClass) || extraBaseClasses.contains(returnClass)) {
//				if(row > 1 && baseClasses.contains(returnClass)) {
//					throw new RuntimeException("基本类型不支持返回不止多条");
//				}
				if(count > 1) {
					throw new RuntimeException("结果集包含多字段，无法映射基本类型");
				}
			}
			
			BeanUtilBean bub = new BeanUtilBean();
			List list = new ArrayList();
			while(rs.next()) {
				Object returnObj = null;
				if(baseClasses.contains(returnClass)) {
					throw new RuntimeException("基本类型不支持返回不止多条");
				} else if(extraBaseClasses.contains(returnClass)) {
					returnObj = rs.getObject(1);
				} else {
					try {
						returnObj = returnClass.newInstance();
					} catch (Exception e) {
						throw new RuntimeException(e);
					}
					for(int i=0;i<count;i++) {
						int column = i + 1;
						String label = rsmd.getColumnLabel(column);
						
						Map<String, String> columnMapping = resultMap.getColumnMapping();
						boolean hasColumn = columnMapping.containsKey(label);
						String propertyName = null;
						if(!hasColumn) {
							propertyName = label;
						} else {
							propertyName = columnMapping.get(label);
						}
						
						if(Map.class.isAssignableFrom(returnClass)) {
							bub.setProperty(returnObj, propertyName, rs.getObject(i+1));
						} else if(bub.hasProperty(returnObj, propertyName)) {
							bub.setProperty(returnObj, propertyName, rs.getObject(i+1));
						}
					}
				}
				
				list.add(returnObj);
			}
			return list;
		} catch (SQLException e) {
			e.printStackTrace();
		}
		return null;
	}
}
